home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / General / GCC 1.37.1r15 / Machines / sparc.md < prev    next >
Text File  |  1990-03-14  |  67KB  |  2,328 lines

  1. ;;- Machine description for SPARC chip for GNU C compiler
  2. ;;   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  3. ;;   Contributed by Michael Tiemann (tiemann@mcc.com)
  4.  
  5. ;; This file is part of GNU CC.
  6.  
  7. ;; GNU CC is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 1, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU CC is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU CC; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  
  22. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
  23.  
  24. ;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
  25. ;;- updates for most instructions.
  26.  
  27. ;;- Operand classes for the register allocator:
  28.  
  29. ;; Compare instructions.
  30. ;; This controls RTL generation and register allocation.
  31.  
  32. ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
  33.  
  34. (define_insn "cmpsi"
  35.   [(set (cc0)
  36.     (compare (match_operand:SI 0 "arith_operand" "r,rI")
  37.          (match_operand:SI 1 "arith_operand" "I,r")))]
  38.   ""
  39.   "*
  40. {
  41.   if (! REG_P (operands[0]))
  42.     {
  43.       cc_status.flags |= CC_REVERSED;
  44.       return \"cmp %1,%0\";
  45.     }
  46.   return \"cmp %0,%1\";
  47. }")
  48.  
  49. (define_expand "cmpdf"
  50.   [(set (cc0)
  51.     (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
  52.          (match_operand:DF 1 "nonmemory_operand" "G,f")))]
  53.   ""
  54.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));")
  55.  
  56. (define_insn ""
  57.   [(set (cc0)
  58.     (compare (match_operand:DF 0 "nonmemory_operand" "f,fG")
  59.          (match_operand:DF 1 "nonmemory_operand" "G,f")))]
  60.   ""
  61.   "*
  62. {
  63.   if (GET_CODE (operands[0]) == CONST_DOUBLE
  64.       || GET_CODE (operands[1]) == CONST_DOUBLE)
  65.     make_f0_contain_0 (2);
  66.  
  67.   cc_status.flags |= CC_IN_FCCR;
  68.   if (GET_CODE (operands[0]) == CONST_DOUBLE)
  69.     return \"fcmped %%f0,%1\;nop\";
  70.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  71.     return \"fcmped %0,%%f0\;nop\";
  72.   return \"fcmped %0,%1\;nop\";
  73. }")
  74.  
  75. (define_expand "cmpsf"
  76.   [(set (cc0)
  77.     (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
  78.          (match_operand:SF 1 "nonmemory_operand" "G,f")))]
  79.   ""
  80.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));")
  81.  
  82. (define_insn ""
  83.   [(set (cc0)
  84.     (compare (match_operand:SF 0 "nonmemory_operand" "f,fG")
  85.          (match_operand:SF 1 "nonmemory_operand" "G,f")))]
  86.   ""
  87.   "*
  88. {
  89.   if (GET_CODE (operands[0]) == CONST_DOUBLE
  90.       || GET_CODE (operands[1]) == CONST_DOUBLE)
  91.     make_f0_contain_0 (1);
  92.  
  93.   cc_status.flags |= CC_IN_FCCR;
  94.   if (GET_CODE (operands[0]) == CONST_DOUBLE)
  95.     return \"fcmpes %%f0,%1\;nop\";
  96.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  97.     return \"fcmpes %0,%%f0\;nop\";
  98.   return \"fcmpes %0,%1\;nop\";
  99. }")
  100.  
  101. ;; Put tstsi first among test insns so it matches a CONST_INT operand.
  102.  
  103. (define_insn "tstsi"
  104.   [(set (cc0)
  105.     (match_operand:SI 0 "register_operand" "r"))]
  106.   ""
  107.   "tst %0")
  108.  
  109. ;; Need this to take a general operand because cse can make
  110. ;; a CONST which won't be in a register.
  111. (define_insn ""
  112.   [(set (cc0)
  113.     (match_operand:SI 0 "immediate_operand" "i"))]
  114.   ""
  115.   "set %0,%%g1\;tst %%g1")
  116.  
  117. ;; Optimize the case of following a reg-reg move with a test
  118. ;; of reg just moved.
  119.  
  120. (define_peephole
  121.   [(set (match_operand:SI 0 "register_operand" "=r")
  122.     (match_operand:SI 1 "register_operand" "r"))
  123.    (set (cc0) (match_operand:SI 2 "register_operand" "r"))]
  124.   "operands[2] == operands[0]
  125.    || operands[2] == operands[1]"
  126.   "orcc %1,%%g0,%0 ! 2-insn combine")
  127.  
  128. ;; Optimize 5(6) insn sequence to 3(4) insns.
  129. ;; These patterns could also optimize more complicated sets
  130. ;; before conditional branches.
  131.  
  132. ;; Turned off because (1) this case is rarely encounted
  133. ;; (2) to be correct, more conditions must be checked
  134. ;; (3) the conditions must be checked with rtx_equal_p, not ==
  135. ;; (4) when branch scheduling is added to the compiler,
  136. ;;     this optimization will be performed by the branch scheduler
  137. ;; Bottom line: it is not worth the trouble of fixing or
  138. ;; maintaining it.
  139.  
  140. ;(define_peephole
  141. ;  [(set (match_operand:SI 0 "register_operand" "=r")
  142. ;    (match_operand:SI 1 "general_operand" "g"))
  143. ;   (set (match_operand:SI 2 "register_operand" "=r")
  144. ;    (match_operand:SI 3 "reg_or_0_operand" "rJ"))
  145. ;   (set (cc0) (match_operand:SI 4 "register_operand" "r"))
  146. ;   (set (pc) (match_operand 5 "" ""))]
  147. ;  "GET_CODE (operands[5]) == IF_THEN_ELSE
  148. ;   && operands[0] != operands[3]
  149. ;   && ! reg_mentioned_p (operands[2], operands[1])
  150. ;   && (operands[4] == operands[0]
  151. ;       || operands[4] == operands[2]
  152. ;       || operands[4] == operands[3])"
  153. ;  "*
  154. ;{
  155. ;  rtx xoperands[2];
  156. ;  int parity;
  157. ;  xoperands[0] = XEXP (operands[5], 0);
  158. ;  if (GET_CODE (XEXP (operands[5], 1)) == PC)
  159. ;    {
  160. ;      parity = 1;
  161. ;      xoperands[1] = XEXP (XEXP (operands[5], 2), 0);
  162. ;    }
  163. ;  else
  164. ;    {
  165. ;      parity = 0;
  166. ;      xoperands[1] = XEXP (XEXP (operands[5], 1), 0);
  167. ;    }
  168. ;
  169. ;  if (operands[4] == operands[0])
  170. ;    {
  171. ;      /* Although the constraints for operands[1] permit a general
  172. ;     operand (and hence possibly a const_int), we know that
  173. ;     in this branch it cannot be a CONST_INT, since that would give
  174. ;     us a fixed condition, and those should have been optimized away.  */
  175. ;      if (REG_P (operands[1]))
  176. ;    output_asm_insn (\"orcc %1,%%g0,%0 ! 3-insn reorder\", operands);
  177. ;      else if (GET_CODE (operands[1]) != MEM)
  178. ;    abort ();
  179. ;      else
  180. ;    {
  181. ;      if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  182. ;        output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;tst %0 ! 4-insn reorder\", operands);
  183. ;      else
  184. ;        output_asm_insn (\"ld %1,%0\;tst %0 ! 3.5-insn reorder\", operands);
  185. ;    }
  186. ;      XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 2);
  187. ;      XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 3);
  188. ;    }
  189. ;  else
  190. ;    {
  191. ;      output_asm_insn (\"orcc %3,%%g0,%2 ! 3-insn reorder\", operands);
  192. ;    }
  193. ;  if (parity)
  194. ;    return output_delayed_branch (\"b%N0 %l1\", xoperands, insn);
  195. ;  else
  196. ;    return output_delayed_branch (\"b%C0 %l1\", xoperands, insn);
  197. ;}")
  198.  
  199. ;; By default, operations don't set the condition codes.
  200. ;; These patterns allow cc's to be set, while doing some work
  201.  
  202. (define_insn ""
  203.   [(set (cc0)
  204.     (zero_extend:SI (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)))]
  205.   ""
  206.   "andcc %0,0xff,%%g0")
  207.  
  208. (define_insn ""
  209.   [(set (cc0)
  210.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  211.          (match_operand:SI 1 "arith_operand" "rI")))]
  212.   ""
  213.   "addcc %0,%1,%%g0")
  214.  
  215. (define_insn ""
  216.   [(set (cc0)
  217.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  218.          (match_operand:SI 1 "arith_operand" "rI")))
  219.    (set (match_operand:SI 2 "register_operand" "=r")
  220.     (plus:SI (match_dup 0) (match_dup 1)))]
  221.   ""
  222.   "addcc %0,%1,%2")
  223.  
  224. (define_insn ""
  225.   [(set (cc0)
  226.     (minus:SI (match_operand:SI 0 "register_operand" "r")
  227.           (match_operand:SI 1 "arith_operand" "rI")))
  228.    (set (match_operand:SI 2 "register_operand" "=r")
  229.     (minus:SI (match_dup 0) (match_dup 1)))]
  230.   ""
  231.   "subcc %0,%1,%2")
  232.  
  233. (define_insn ""
  234.   [(set (cc0)
  235.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  236.         (match_operand:SI 1 "arith_operand" "rI")))]
  237.   ""
  238.   "andcc %0,%1,%%g0")
  239.  
  240. (define_insn ""
  241.   [(set (cc0)
  242.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  243.         (match_operand:SI 1 "arith_operand" "rI")))
  244.    (set (match_operand:SI 2 "register_operand" "=r")
  245.     (and:SI (match_dup 0) (match_dup 1)))]
  246.   ""
  247.   "andcc %0,%1,%2")
  248.  
  249. (define_insn ""
  250.   [(set (cc0)
  251.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  252.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  253.   ""
  254.   "andncc %0,%1,%%g0")
  255.  
  256. (define_insn ""
  257.   [(set (cc0)
  258.     (and:SI (match_operand:SI 0 "register_operand" "r%")
  259.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  260.    (set (match_operand:SI 2 "register_operand" "=r")
  261.     (and:SI (match_dup 0) (not:SI (match_dup 1))))]
  262.   ""
  263.   "andncc %0,%1,%2")
  264.  
  265. (define_insn ""
  266.   [(set (cc0)
  267.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  268.         (match_operand:SI 1 "arith_operand" "rI")))]
  269.   ""
  270.   "orcc %0,%1,%%g0")
  271.  
  272. (define_insn ""
  273.   [(set (cc0)
  274.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  275.         (match_operand:SI 1 "arith_operand" "rI")))
  276.    (set (match_operand:SI 2 "register_operand" "=r")
  277.     (ior:SI (match_dup 0) (match_dup 1)))]
  278.   ""
  279.   "orcc %0,%1,%2")
  280.  
  281. (define_insn ""
  282.   [(set (cc0)
  283.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  284.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  285.   ""
  286.   "orncc %0,%1,%%g0")
  287.  
  288. (define_insn ""
  289.   [(set (cc0)
  290.     (ior:SI (match_operand:SI 0 "register_operand" "r%")
  291.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  292.    (set (match_operand:SI 2 "register_operand" "=r")
  293.     (ior:SI (match_dup 0) (not:SI (match_dup 1))))]
  294.   ""
  295.   "orncc %0,%1,%2")
  296.  
  297. (define_insn ""
  298.   [(set (cc0)
  299.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  300.         (match_operand:SI 1 "arith_operand" "rI")))]
  301.   ""
  302.   "xorcc %0,%1,%%g0")
  303.  
  304. (define_insn ""
  305.   [(set (cc0)
  306.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  307.         (match_operand:SI 1 "arith_operand" "rI")))
  308.    (set (match_operand:SI 2 "register_operand" "=r")
  309.     (xor:SI (match_dup 0) (match_dup 1)))]
  310.   ""
  311.   "xorcc %0,%1,%2")
  312.  
  313. (define_insn ""
  314.   [(set (cc0)
  315.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  316.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))]
  317.   ""
  318.   "xnorcc %0,%1,%%g0")
  319.  
  320. (define_insn ""
  321.   [(set (cc0)
  322.     (xor:SI (match_operand:SI 0 "register_operand" "r%")
  323.         (not:SI (match_operand:SI 1 "arith_operand" "rI"))))
  324.    (set (match_operand:SI 2 "register_operand" "=r")
  325.     (xor:SI (match_dup 0) (not:SI (match_dup 1))))]
  326.   ""
  327.   "xnorcc %0,%1,%2")
  328.  
  329. (define_expand "tstdf"
  330.   [(set (cc0)
  331.     (match_operand:DF 0 "register_operand" "f"))]
  332.   ""
  333.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, DFmode, 32)));")
  334.  
  335. (define_insn ""
  336.   [(set (cc0)
  337.     (match_operand:DF 0 "register_operand" "f"))]
  338.   ""
  339.   "*
  340. {
  341.   make_f0_contain_0 (2);
  342.   cc_status.flags |= CC_IN_FCCR;
  343.   return \"fcmped %0,%%f0\;nop\";
  344. }")
  345.  
  346. (define_expand "tstsf"
  347.   [(set (cc0)
  348.     (match_operand:SF 0 "register_operand" "f"))]
  349.   ""
  350.   "emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SFmode, 32)));")
  351.  
  352. (define_insn ""
  353.   [(set (cc0)
  354.     (match_operand:SF 0 "register_operand" "f"))]
  355.   ""
  356.   "*
  357. {
  358.   make_f0_contain_0 (1);
  359.   cc_status.flags |= CC_IN_FCCR;
  360.   return \"fcmpes %0,%%f0\;nop\";
  361. }")
  362.  
  363. ;; There are no logical links for the condition codes.  This
  364. ;; would not normally be a problem, but on the SPARC (and possibly
  365. ;; other RISC machines), when argument passing, the insn which sets
  366. ;; the condition code and the insn which uses the set condition code
  367. ;; may not be performed adjacently (due to optimizations performed
  368. ;; in combine.c).  To make up for this, we emit insn patterns which
  369. ;; cannot possibly be rearranged on us.
  370. (define_expand "seq"
  371.   [(set (match_operand:SI 0 "general_operand" "=r")
  372.     (eq (cc0) (const_int 0)))]
  373.   ""
  374.   "gen_scc_insn (EQ, VOIDmode, operands); DONE;")
  375.  
  376. (define_expand "sne"
  377.   [(set (match_operand:SI 0 "general_operand" "=r")
  378.     (ne (cc0) (const_int 0)))]
  379.   ""
  380.   "gen_scc_insn (NE, VOIDmode, operands); DONE;")
  381.  
  382. (define_insn ""
  383.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  384.     (match_operator 1 "eq_or_neq"
  385.             [(compare (match_operand:SI 2 "general_operand" "r,rI")
  386.                   (match_operand:SI 3 "general_operand" "I,r"))
  387.              (const_int 0)]))]
  388.   ""
  389.   "*
  390. {
  391.   CC_STATUS_INIT;
  392.   cc_status.value1 = operands[0];
  393.   if (! REG_P (operands[2]))
  394.     {
  395.       output_asm_insn (\"cmp %3,%2\", operands);
  396.       cc_status.flags |= CC_REVERSED;
  397.     }
  398.   else
  399.     output_asm_insn (\"cmp %2,%3\", operands);
  400.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  401. }")
  402.  
  403. (define_insn ""
  404.   [(set (match_operand:SI 0 "general_operand" "=r")
  405.     (match_operator 1 "eq_or_neq"
  406.             [(match_operand:SI 2 "general_operand" "r")
  407.              (const_int 0)]))]
  408.   ""
  409.   "*
  410. {
  411.   CC_STATUS_INIT;
  412.   cc_status.value1 = operands[0];
  413.   output_asm_insn (\"tst %2\", operands);
  414.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  415. }")
  416.  
  417. (define_insn ""
  418.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  419.     (match_operator 1 "eq_or_neq"
  420.             [(compare (match_operand:DF 2 "general_operand" "f,fG")
  421.                   (match_operand:DF 3 "general_operand" "G,f"))
  422.              (const_int 0)]))]
  423.   ""
  424.   "*
  425. {
  426.   CC_STATUS_INIT;
  427.   cc_status.value1 = operands[0];
  428.   cc_status.flags |= CC_IN_FCCR;
  429.  
  430.   if (GET_CODE (operands[2]) == CONST_DOUBLE
  431.       || GET_CODE (operands[3]) == CONST_DOUBLE)
  432.     make_f0_contain_0 (2);
  433.  
  434.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  435.     output_asm_insn (\"fcmped %%f0,%3\;nop\", operands);
  436.   else if (GET_CODE (operands[3]) == CONST_DOUBLE)
  437.     output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
  438.   else output_asm_insn (\"fcmped %2,%3\;nop\", operands);
  439.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  440. }")
  441.  
  442. (define_insn ""
  443.   [(set (match_operand:SI 0 "general_operand" "=r")
  444.     (match_operator 1 "eq_or_neq"
  445.             [(match_operand:DF 2 "general_operand" "f")
  446.              (const_int 0)]))]
  447.   ""
  448.   "*
  449. {
  450.   CC_STATUS_INIT;
  451.   cc_status.value1 = operands[0];
  452.   cc_status.flags |= CC_IN_FCCR;
  453.  
  454.   make_f0_contain_0 (2);
  455.   output_asm_insn (\"fcmped %2,%%f0\;nop\", operands);
  456.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  457. }")
  458.  
  459. (define_insn ""
  460.   [(set (match_operand:SI 0 "general_operand" "=r,r")
  461.     (match_operator 1 "eq_or_neq"
  462.             [(compare (match_operand:SF 2 "general_operand" "f,fG")
  463.                   (match_operand:SF 3 "general_operand" "G,f"))
  464.              (const_int 0)]))]
  465.   ""
  466.   "*
  467. {
  468.   CC_STATUS_INIT;
  469.   cc_status.value1 = operands[0];
  470.   cc_status.flags |= CC_IN_FCCR;
  471.  
  472.   if (GET_CODE (operands[2]) == CONST_DOUBLE
  473.       || GET_CODE (operands[3]) == CONST_DOUBLE)
  474.     make_f0_contain_0 (1);
  475.  
  476.   if (GET_CODE (operands[2]) == CONST_DOUBLE)
  477.     output_asm_insn (\"fcmpes %%f0,%3\;nop\", operands);
  478.   else if (GET_CODE (operands[3]) == CONST_DOUBLE)
  479.     output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
  480.   else output_asm_insn (\"fcmpes %2,%3\;nop\", operands);
  481.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  482. }")
  483.  
  484. (define_insn ""
  485.   [(set (match_operand:SI 0 "general_operand" "=r")
  486.     (match_operator 1 "eq_or_neq"
  487.             [(match_operand:SF 2 "general_operand" "f")
  488.              (const_int 0)]))]
  489.   ""
  490.   "*
  491. {
  492.   CC_STATUS_INIT;
  493.   cc_status.value1 = operands[0];
  494.   cc_status.flags |= CC_IN_FCCR;
  495.  
  496.   make_f0_contain_0 (1);
  497.   output_asm_insn (\"fcmpes %2,%%f0\;nop\", operands);
  498.   return output_scc_insn (GET_CODE (operands[1]), operands[0]);
  499. }")
  500.  
  501. ;; These control RTL generation for conditional jump insns
  502. ;; and match them for register allocation.
  503.  
  504. (define_insn "beq"
  505.   [(set (pc)
  506.     (if_then_else (eq (cc0)
  507.               (const_int 0))
  508.               (label_ref (match_operand 0 "" ""))
  509.               (pc)))]
  510.   ""
  511.   "*
  512. {
  513.   if (cc_prev_status.flags & CC_IN_FCCR)
  514.     return \"fbe %l0\;nop\";
  515.   return \"be %l0\;nop\";
  516. }")
  517.  
  518. (define_insn "bne"
  519.   [(set (pc)
  520.     (if_then_else (ne (cc0)
  521.               (const_int 0))
  522.               (label_ref (match_operand 0 "" ""))
  523.               (pc)))]
  524.   ""
  525.   "*
  526. {
  527.   if (cc_prev_status.flags & CC_IN_FCCR)
  528.     return \"fbne %l0\;nop\";
  529.   return \"bne %l0\;nop\";
  530. }")
  531.  
  532. (define_insn "bgt"
  533.   [(set (pc)
  534.     (if_then_else (gt (cc0)
  535.               (const_int 0))
  536.               (label_ref (match_operand 0 "" ""))
  537.               (pc)))]
  538.   ""
  539.   "*
  540. {
  541.   if (cc_prev_status.flags & CC_IN_FCCR)
  542.     return \"fbg %l0\;nop\";
  543.   return \"bg %l0\;nop\";
  544. }")
  545.  
  546. (define_insn "bgtu"
  547.   [(set (pc)
  548.     (if_then_else (gtu (cc0)
  549.                (const_int 0))
  550.               (label_ref (match_operand 0 "" ""))
  551.               (pc)))]
  552.   ""
  553.   "*
  554. {
  555.   if (cc_prev_status.flags & CC_IN_FCCR)
  556.     abort ();
  557.   return \"bgu %l0\;nop\";
  558. }")
  559.  
  560. (define_insn "blt"
  561.   [(set (pc)
  562.     (if_then_else (lt (cc0)
  563.               (const_int 0))
  564.               (label_ref (match_operand 0 "" ""))
  565.               (pc)))]
  566.   ""
  567.   "*
  568. {
  569.   if (cc_prev_status.flags & CC_IN_FCCR)
  570.     return \"fbl %l0\;nop\";
  571.   return \"bl %l0\;nop\";
  572. }")
  573.  
  574. (define_insn "bltu"
  575.   [(set (pc)
  576.     (if_then_else (ltu (cc0)
  577.                (const_int 0))
  578.               (label_ref (match_operand 0 "" ""))
  579.               (pc)))]
  580.   ""
  581.   "*
  582. {
  583.   if (cc_prev_status.flags & CC_IN_FCCR)
  584.     abort ();
  585.   return \"blu %l0\;nop\";
  586. }")
  587.  
  588. (define_insn "bge"
  589.   [(set (pc)
  590.     (if_then_else (ge (cc0)
  591.               (const_int 0))
  592.               (label_ref (match_operand 0 "" ""))
  593.               (pc)))]
  594.   ""
  595.   "*
  596. {
  597.   if (cc_prev_status.flags & CC_IN_FCCR)
  598.     return \"fbge %l0\;nop\";
  599.   return \"bge %l0\;nop\";
  600. }")
  601.  
  602. (define_insn "bgeu"
  603.   [(set (pc)
  604.     (if_then_else (geu (cc0)
  605.                (const_int 0))
  606.               (label_ref (match_operand 0 "" ""))
  607.               (pc)))]
  608.   ""
  609.   "*
  610. {
  611.   if (cc_prev_status.flags & CC_IN_FCCR)
  612.     abort ();
  613.   return \"bgeu %l0\;nop\";
  614. }")
  615.  
  616. (define_insn "ble"
  617.   [(set (pc)
  618.     (if_then_else (le (cc0)
  619.               (const_int 0))
  620.               (label_ref (match_operand 0 "" ""))
  621.               (pc)))]
  622.   ""
  623.   "*
  624. {
  625.   if (cc_prev_status.flags & CC_IN_FCCR)
  626.     return \"fble %l0\;nop\";
  627.   return \"ble %l0\;nop\";
  628. }")
  629.  
  630. (define_insn "bleu"
  631.   [(set (pc)
  632.     (if_then_else (leu (cc0)
  633.                (const_int 0))
  634.               (label_ref (match_operand 0 "" ""))
  635.               (pc)))]
  636.   ""
  637.   "*
  638. {
  639.   if (cc_prev_status.flags & CC_IN_FCCR)
  640.     abort ();
  641.   return \"bleu %l0\;nop\";
  642. }")
  643.  
  644. ;; This matches inverted jump insns for register allocation.
  645.  
  646. (define_insn ""
  647.   [(set (pc)
  648.     (if_then_else (match_operator 0 "relop" [(cc0) (const_int 0)])
  649.               (pc)
  650.               (label_ref (match_operand 1 "" ""))))]
  651.   ""
  652.   "*
  653. {
  654.   if (cc_prev_status.flags & CC_IN_FCCR)
  655.     return \"fb%F0 %l1\;nop\";
  656.   return \"b%N0 %l1\;nop\";
  657. }")
  658.  
  659. ;; Move instructions
  660.  
  661. (define_insn "swapsi"
  662.   [(set (match_operand:SI 0 "general_operand" "r,rm")
  663.     (match_operand:SI 1 "general_operand" "m,r"))
  664.    (set (match_dup 1) (match_dup 0))]
  665.   ""
  666.   "*
  667. {
  668.   if (GET_CODE (operands[1]) == MEM)
  669.     {
  670.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  671.     output_asm_insn (\"set %a1,%%g1\", operands),
  672.     operands[1] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1)),
  673.     cc_status.flags &= ~CC_KNOW_HI_G1;
  674.       output_asm_insn (\"swap %1,%0\", operands);
  675.     }
  676.   if (REG_P (operands[0]))
  677.     {
  678.       if (REGNO (operands[0]) == REGNO (operands[1]))
  679.     return \"\";
  680.       return \"xor %0,%1,%0\;xor %1,%0,%1\;xor %0,%1,%0\";
  681.     }
  682.   if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  683.     {
  684.       output_asm_insn (\"set %a0,%%g1\", operands);
  685.       operands[0] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 1));
  686.       cc_status.flags &= ~CC_KNOW_HI_G1;
  687.     }
  688.   return \"swap %0,%1\";
  689. }")
  690.  
  691. (define_insn "movsi"
  692.   [(set (match_operand:SI 0 "general_operand" "=r,m")
  693.     (match_operand:SI 1 "general_operand" "rmif,rJ"))]
  694.   ""
  695.   "*
  696. {
  697.   if (GET_CODE (operands[0]) == MEM)
  698.     {
  699.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  700.     return output_store (operands);
  701.       return \"st %r1,%0\";
  702.     }
  703.   if (GET_CODE (operands[1]) == MEM)
  704.     {
  705.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  706.     return output_load_fixed (operands);
  707.       return \"ld %1,%0\";
  708.     }
  709.   if (FP_REG_P (operands[1]))
  710.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  711.   if (REG_P (operands[1])
  712.       || (GET_CODE (operands[1]) == CONST_INT
  713.       && SMALL_INT (operands[1])))
  714.     return \"mov %1,%0\";
  715.   if (GET_CODE (operands[1]) == CONST_INT
  716.       && (INTVAL (operands[1]) & 0x3ff) == 0)
  717.     return \"sethi %%hi(%1),%0\";
  718.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  719. }")
  720.  
  721. (define_insn "movhi"
  722.   [(set (match_operand:HI 0 "general_operand" "=r,m")
  723.     (match_operand:HI 1 "general_operand" "rmi,rJ"))]
  724.   ""
  725.   "*
  726. {
  727.   if (GET_CODE (operands[0]) == MEM)
  728.     {
  729.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  730.     return output_store (operands);
  731.       return \"sth %r1,%0\";
  732.     }
  733.   if (GET_CODE (operands[1]) == MEM)
  734.     {
  735.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  736.     return output_load_fixed (operands);
  737.       return \"ldsh %1,%0\";
  738.     }
  739.   if (REG_P (operands[1])
  740.       || (GET_CODE (operands[1]) == CONST_INT
  741.       && SMALL_INT (operands[1])))
  742.     return \"mov %1,%0\";
  743.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  744. }")
  745.  
  746. (define_insn "movqi"
  747.   [(set (match_operand:QI 0 "general_operand" "=r,m")
  748.     (match_operand:QI 1 "general_operand" "rmi,rJ"))]
  749.   ""
  750.   "*
  751. {
  752.   if (GET_CODE (operands[0]) == MEM)
  753.     {
  754.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  755.     return output_store (operands);
  756.       return \"stb %r1,%0\";
  757.     }
  758.   if (GET_CODE (operands[1]) == MEM)
  759.     {
  760.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  761.     return output_load_fixed (operands);
  762.       return \"ldsb %1,%0\";
  763.     }
  764.   if (REG_P (operands[1])
  765.       || (GET_CODE (operands[1]) == CONST_INT
  766.       && SMALL_INT (operands[1])))
  767.     return \"mov %1,%0\";
  768.   return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  769. }")
  770.  
  771. ;; The definition of this insn does not really explain what it does,
  772. ;; but it should suffice
  773. ;; that anything generated as this insn will be recognized as one
  774. ;; and that it won't successfully combine with anything.
  775. (define_expand "movstrsi"
  776.   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
  777.            (mem:BLK (match_operand:BLK 1 "general_operand" "")))
  778.           (use (match_operand:SI 2 "arith32_operand" ""))
  779.           (use (match_operand:SI 3 "immediate_operand" ""))
  780.           (clobber (match_dup 4))
  781.           (clobber (match_dup 0))
  782.           (clobber (match_dup 1))])]
  783.   ""
  784.   "
  785. {
  786.   operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
  787.   operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
  788.   operands[4] = gen_reg_rtx (SImode);
  789. }")
  790.  
  791. (define_insn ""
  792.   [(set (mem:BLK (match_operand:SI 0 "register_operand" "r"))
  793.     (mem:BLK (match_operand:SI 1 "register_operand" "r")))
  794.    (use (match_operand:SI 2 "arith32_operand" "rn"))
  795.    (use (match_operand:SI 3 "immediate_operand" "i"))
  796.    (clobber (match_operand:SI 4 "register_operand" "=r"))
  797.    (clobber (match_operand:SI 5 "register_operand" "=0"))
  798.    (clobber (match_operand:SI 6 "register_operand" "=1"))]
  799.   ""
  800.   "* return output_block_move (operands);")
  801.  
  802. ;; Floating point move insns
  803.  
  804. ;; This pattern forces (set (reg:DF ...) (const_double ...))
  805. ;; to be reloaded by putting the constant into memory.
  806. ;; It must come before the more general movdf pattern.
  807. (define_insn ""
  808.   [(set (match_operand:DF 0 "general_operand" "=r,f,o")
  809.     (match_operand:DF 1 "" "mG,m,G"))]
  810.   "GET_CODE (operands[1]) == CONST_DOUBLE"
  811.   "*
  812. {
  813.   if (FP_REG_P (operands[0]))
  814.     return output_fp_move_double (operands);
  815.   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
  816.     {
  817.       operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  818.       return \"mov %%g0,%0\;mov %%g0,%1\";
  819.     }
  820.   if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
  821.     {
  822.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  823.     {
  824.       if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  825.          && XEXP (operands[0], 0) == cc_prev_status.mdep))
  826.         {
  827.           cc_status.flags |= CC_KNOW_HI_G1;
  828.           cc_status.mdep = XEXP (operands[0], 0);
  829.           output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  830.         }
  831.       return \"st %%g0,[%%g1+%%lo(%%m0)]\;st %%g0,[%%g1+%%lo(%%m0)+4]\";
  832.     }
  833.       operands[1] = adj_offsettable_operand (operands[0], 4);
  834.       return \"st %%g0,%0\;st %%g0,%1\";
  835.     }
  836.   return output_move_double (operands);
  837. }")
  838.  
  839. (define_insn "movdf"
  840.   [(set (match_operand:DF 0 "general_operand" "=rm,&r,?f,?rm")
  841.     (match_operand:DF 1 "general_operand" "r,m,rfm,f"))]
  842.   ""
  843.   "*
  844. {
  845.   if (GET_CODE (operands[0]) == MEM
  846.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  847.     return output_store (operands);
  848.   if (GET_CODE (operands[1]) == MEM
  849.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  850.     return output_load_floating (operands);
  851.  
  852.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  853.     return output_fp_move_double (operands);
  854.   return output_move_double (operands);
  855. }")
  856.  
  857. (define_insn "movdi"
  858.   [(set (match_operand:DI 0 "general_operand" "=rm,&r,?f,?rm")
  859.     (match_operand:DI 1 "general_operand" "r,mi,rfm,f"))]
  860.   ""
  861.   "*
  862. {
  863.   if (GET_CODE (operands[0]) == MEM
  864.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  865.     return output_store (operands);
  866.   if (GET_CODE (operands[1]) == MEM
  867.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  868.     return output_load_fixed (operands);
  869.  
  870.   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
  871.     return output_fp_move_double (operands);
  872.   return output_move_double (operands);
  873. }")
  874.  
  875. (define_insn "movsf"
  876.   [(set (match_operand:SF 0 "general_operand" "=rf,m")
  877.     (match_operand:SF 1 "general_operand" "rfm,rf"))]
  878.   ""
  879.   "*
  880. {
  881.   if (GET_CODE (operands[0]) == MEM
  882.       && CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  883.     return output_store (operands);
  884.   if (GET_CODE (operands[1]) == MEM
  885.       && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  886.     return output_load_floating (operands);
  887.   if (FP_REG_P (operands[0]))
  888.     {
  889.       if (FP_REG_P (operands[1]))
  890.     return \"fmovs %1,%0\";
  891.       if (GET_CODE (operands[1]) == REG)
  892.         return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  893.       if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  894.     {
  895.       cc_status.flags |= CC_KNOW_HI_G1;
  896.       cc_status.mdep = XEXP (operands[1], 0);
  897.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\";
  898.     }
  899.       return \"ld %1,%0\";
  900.     }
  901.   if (FP_REG_P (operands[1]))
  902.     {
  903.       if (GET_CODE (operands[0]) == REG)
  904.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\";
  905.       if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  906.     {
  907.       if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  908.          && XEXP (operands[0], 0) == cc_prev_status.mdep))
  909.         {
  910.           cc_status.flags |= CC_KNOW_HI_G1;
  911.           cc_status.mdep = XEXP (operands[0], 0);
  912.           output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  913.         }
  914.       return \"st %r1,[%%g1+%%lo(%m0)]\";
  915.     }
  916.       return \"st %r1,%0\";
  917.     }
  918.   if (GET_CODE (operands[0]) == MEM)
  919.     return \"st %r1,%0\";
  920.   if (GET_CODE (operands[1]) == MEM)
  921.     return \"ld %1,%0\";
  922.   return \"mov %1,%0\";
  923. }")
  924.  
  925. ;;- truncation instructions
  926. (define_insn "truncsiqi2"
  927.   [(set (match_operand:QI 0 "general_operand" "=g")
  928.     (truncate:QI
  929.      (match_operand:SI 1 "register_operand" "r")))]
  930.   ""
  931.   "*
  932. {
  933.   if (GET_CODE (operands[0]) == MEM)
  934.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  935.       {
  936.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  937.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  938.       {
  939.         cc_status.flags |= CC_KNOW_HI_G1;
  940.         cc_status.mdep = XEXP (operands[0], 0);
  941.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  942.       }
  943.     return \"stb %1,[%%g1+%%lo(%m0)]\";
  944.       }
  945.     else
  946.       return \"stb %1,%0\";
  947.   return \"mov %1,%0\";
  948. }")
  949.  
  950. (define_insn "trunchiqi2"
  951.   [(set (match_operand:QI 0 "general_operand" "=g")
  952.     (truncate:QI
  953.      (match_operand:HI 1 "register_operand" "r")))]
  954.   ""
  955.   "*
  956. {
  957.   if (GET_CODE (operands[0]) == MEM)
  958.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  959.       {
  960.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  961.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  962.       {
  963.         cc_status.flags |= CC_KNOW_HI_G1;
  964.         cc_status.mdep = XEXP (operands[0], 0);
  965.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  966.       }
  967.     return \"stb %1,[%%g1+%%lo(%m0)]\";
  968.       }
  969.     else
  970.       return \"stb %1,%0\";
  971.   return \"mov %1,%0\";
  972. }")
  973.  
  974. (define_insn "truncsihi2"
  975.   [(set (match_operand:HI 0 "general_operand" "=g")
  976.     (truncate:HI
  977.      (match_operand:SI 1 "register_operand" "r")))]
  978.   ""
  979.   "*
  980. {
  981.   if (GET_CODE (operands[0]) == MEM)
  982.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  983.       {
  984.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  985.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  986.       {
  987.         cc_status.flags |= CC_KNOW_HI_G1;
  988.         cc_status.mdep = XEXP (operands[0], 0);
  989.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  990.       }
  991.     return \"sth %1,[%%g1+%%lo(%m0)]\";
  992.       }
  993.     else
  994.       return \"sth %1,%0\";
  995.   return \"mov %1,%0\";
  996. }")
  997.  
  998. ;;- zero extension instructions
  999.  
  1000. ;; Note that the one starting from HImode comes before those for QImode
  1001. ;; so that a constant operand will match HImode, not QImode.
  1002.  
  1003. (define_insn "zero_extendhisi2"
  1004.   [(set (match_operand:SI 0 "register_operand" "=r")
  1005.     (zero_extend:SI
  1006.      (match_operand:HI 1 "general_operand" "g")))]
  1007.   ""
  1008.   "*
  1009. {
  1010.   if (REG_P (operands[1]))
  1011.     return \"sll %1,0x10,%0\;srl %0,0x10,%0\";
  1012.   if (GET_CODE (operands[1]) == CONST_INT)
  1013.     {
  1014.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1015.                  INTVAL (operands[1]) & 0xffff);
  1016.       output_asm_insn (\"set %1,%0\", operands);
  1017.       return \"\";
  1018.     }
  1019.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1020.     {
  1021.       cc_status.flags |= CC_KNOW_HI_G1;
  1022.       cc_status.mdep = XEXP (operands[1], 0);
  1023.       return \"sethi %%hi(%m1),%%g1\;lduh [%%g1+%%lo(%m1)],%0\";
  1024.     }
  1025.   else
  1026.     return \"lduh %1,%0\";
  1027. }")
  1028.  
  1029. (define_insn "zero_extendqihi2"
  1030.   [(set (match_operand:HI 0 "register_operand" "=r")
  1031.     (zero_extend:HI
  1032.      (match_operand:QI 1 "general_operand" "g")))]
  1033.   ""
  1034.   "*
  1035. {
  1036.   if (REG_P (operands[1]))
  1037.     return \"and %1,0xff,%0\";
  1038.   if (GET_CODE (operands[1]) == CONST_INT)
  1039.     {
  1040.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1041.                  INTVAL (operands[1]) & 0xff);
  1042.       output_asm_insn (\"set %1,%0\", operands);
  1043.       return \"\";
  1044.     }
  1045.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1046.     {
  1047.       cc_status.flags |= CC_KNOW_HI_G1;
  1048.       cc_status.mdep = XEXP (operands[1], 0);
  1049.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1050.     }
  1051.   else
  1052.     return \"ldub %1,%0\";
  1053. }")
  1054.  
  1055. (define_insn "zero_extendqisi2"
  1056.   [(set (match_operand:SI 0 "register_operand" "=r")
  1057.     (zero_extend:SI
  1058.      (match_operand:QI 1 "general_operand" "g")))]
  1059.   ""
  1060.   "*
  1061. {
  1062.   if (REG_P (operands[1]))
  1063.     return \"and %1,0xff,%0\";
  1064.   if (GET_CODE (operands[1]) == CONST_INT)
  1065.     {
  1066.       operands[1] = gen_rtx (CONST_INT, VOIDmode,
  1067.                  INTVAL (operands[1]) & 0xff);
  1068.       output_asm_insn (\"set %1,%0\", operands);
  1069.       return \"\";
  1070.     }
  1071.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1072.     {
  1073.       cc_status.flags |= CC_KNOW_HI_G1;
  1074.       cc_status.mdep = XEXP (operands[1], 0);
  1075.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1076.     }
  1077.   else
  1078.     return \"ldub %1,%0\";
  1079. }")
  1080.  
  1081. ;;- sign extension instructions
  1082. ;; Note that the one starting from HImode comes before those for QImode
  1083. ;; so that a constant operand will match HImode, not QImode.
  1084.  
  1085. (define_insn "extendhisi2"
  1086.   [(set (match_operand:SI 0 "register_operand" "=r")
  1087.     (sign_extend:SI
  1088.      (match_operand:HI 1 "general_operand" "g")))]
  1089.   ""
  1090.   "*
  1091. {
  1092.   if (REG_P (operands[1]))
  1093.     return \"sll %1,0x10,%0\;sra %0,0x10,%0\";
  1094.   if (GET_CODE (operands[1]) == CONST_INT)
  1095.     {
  1096.       int i = (short)INTVAL (operands[1]);
  1097.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1098.       output_asm_insn (\"set %1,%0\", operands);
  1099.       return \"\";
  1100.     }
  1101.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1102.     {
  1103.       cc_status.flags |= CC_KNOW_HI_G1;
  1104.       cc_status.mdep = XEXP (operands[1], 0);
  1105.       return \"sethi %%hi(%m1),%%g1\;ldsh [%%g1+%%lo(%m1)],%0\";
  1106.     }
  1107.   else
  1108.     return \"ldsh %1,%0\";
  1109. }")
  1110.  
  1111. (define_insn "extendqihi2"
  1112.   [(set (match_operand:HI 0 "register_operand" "=r")
  1113.     (sign_extend:HI
  1114.      (match_operand:QI 1 "general_operand" "g")))]
  1115.   ""
  1116.   "*
  1117. {
  1118.   if (REG_P (operands[1]))
  1119.     return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
  1120.   if (GET_CODE (operands[1]) == CONST_INT)
  1121.     {
  1122.       int i = (char)INTVAL (operands[1]);
  1123.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1124.       output_asm_insn (\"set %1,%0\", operands);
  1125.       return \"\";
  1126.     }
  1127.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1128.     {
  1129.       cc_status.flags |= CC_KNOW_HI_G1;
  1130.       cc_status.mdep = XEXP (operands[1], 0);
  1131.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1132.     }
  1133.   else
  1134.     return \"ldsb %1,%0\";
  1135. }")
  1136.  
  1137. (define_insn "extendqisi2"
  1138.   [(set (match_operand:SI 0 "register_operand" "=r")
  1139.     (sign_extend:SI
  1140.      (match_operand:QI 1 "general_operand" "g")))]
  1141.   ""
  1142.   "*
  1143. {
  1144.   if (REG_P (operands[1]))
  1145.     return \"sll %1,0x18,%0\;sra %0,0x18,%0\";
  1146.   if (GET_CODE (operands[1]) == CONST_INT)
  1147.     {
  1148.       int i = (char)INTVAL (operands[1]);
  1149.       operands[1] = gen_rtx (CONST_INT, VOIDmode, i);
  1150.       output_asm_insn (\"set %1,%0\", operands);
  1151.       return \"\";
  1152.     }
  1153.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1154.     {
  1155.       cc_status.flags |= CC_KNOW_HI_G1;
  1156.       cc_status.mdep = XEXP (operands[1], 0);
  1157.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1158.     }
  1159.   else
  1160.     return \"ldsb %1,%0\";
  1161. }")
  1162.  
  1163. ;; Signed bitfield extractions come out looking like
  1164. ;;    (shiftrt (shift (sign_extend <Y>) <C1>) <C2>)
  1165. ;; which we expand poorly as four shift insns.
  1166. ;; These patters yeild two shifts:
  1167. ;;    (shiftrt (shift <Y> <C3>) <C4>)
  1168. (define_insn ""
  1169.   [(set (match_operand:SI 0 "register_operand" "=r")
  1170.     (ashiftrt:SI
  1171.      (sign_extend:SI
  1172.       (match_operand:QI 1 "register_operand" "r"))
  1173.      (match_operand:SI 2 "small_int" "n")))]
  1174.   ""
  1175.   "sll %1,0x18,%0\;sra %0,0x18+%2,%0")
  1176.  
  1177. (define_insn ""
  1178.   [(set (match_operand:SI 0 "register_operand" "=r")
  1179.     (ashiftrt:SI
  1180.      (sign_extend:SI
  1181.       (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r")
  1182.                 (match_operand:SI 2 "small_int" "n")) 0))
  1183.      (match_operand:SI 3 "small_int" "n")))]
  1184.   ""
  1185.   "sll %1,0x18+%2,%0\;sra %0,0x18+%3,%0")
  1186.  
  1187. ;; Special patterns for optimizing bit-field instructions.
  1188.  
  1189. ;; First two patterns are for bitfields that came from memory
  1190. ;; testing only the high bit.  They work with old combiner.
  1191. ;; @@ Actually, the second pattern does not work if we
  1192. ;; @@ need to set the N bit.
  1193. (define_insn ""
  1194.   [(set (cc0)
  1195.     (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1196.                         (const_int 7)) 0)))]
  1197.   "0"
  1198.   "andcc %0,128,%%g0")
  1199.  
  1200. (define_insn ""
  1201.   [(set (cc0)
  1202.     (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1203.                         (const_int 7)) 0)))]
  1204.   "0"
  1205.   "andcc %0,128,%%g0")
  1206.  
  1207. ;; next two patterns are good for bitfields coming from memory
  1208. ;; (via pseudo-register) or from a register, though this optimization
  1209. ;; is only good for values contained wholly within the bottom 13 bits
  1210. (define_insn ""
  1211.   [(set (cc0)
  1212.     (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1213.                  (match_operand:SI 1 "small_int" "n"))
  1214.         (match_operand:SI 2 "small_int" "n")))]
  1215.   "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
  1216.   "andcc %0,%2<<%1,%%g0")
  1217.  
  1218. (define_insn ""
  1219.   [(set (cc0)
  1220.     (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r")
  1221.                  (match_operand:SI 1 "small_int" "n"))
  1222.         (match_operand:SI 2 "small_int" "n")))]
  1223.   "(unsigned)((INTVAL (operands[2]) << INTVAL (operands[1])) + 0x1000) < 0x2000"
  1224.   "andcc %0,%2<<%1,%%g0")
  1225.  
  1226. ;; Conversions between float and double.
  1227.  
  1228. (define_insn "extendsfdf2"
  1229.   [(set (match_operand:DF 0 "register_operand" "=f")
  1230.     (float_extend:DF
  1231.      (match_operand:SF 1 "register_operand" "f")))]
  1232.   ""
  1233.   "fstod %1,%0")
  1234.  
  1235. (define_insn "truncdfsf2"
  1236.   [(set (match_operand:SF 0 "register_operand" "=f")
  1237.     (float_truncate:SF
  1238.      (match_operand:DF 1 "register_operand" "f")))]
  1239.   ""
  1240.   "fdtos %1,%0")
  1241.  
  1242. ;; Conversion between fixed point and floating point.
  1243. ;; Note that among the fix-to-float insns
  1244. ;; the ones that start with SImode come first.
  1245. ;; That is so that an operand that is a CONST_INT
  1246. ;; (and therefore lacks a specific machine mode).
  1247. ;; will be recognized as SImode (which is always valid)
  1248. ;; rather than as QImode or HImode.
  1249.  
  1250. ;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
  1251. ;; to be reloaded by putting the constant into memory.
  1252. ;; It must come before the more general floatsisf2 pattern.
  1253. (define_insn ""
  1254.   [(set (match_operand:SF 0 "general_operand" "=f")
  1255.     (float:SF (match_operand 1 "" "m")))]
  1256.   "GET_CODE (operands[1]) == CONST_INT"
  1257.   "*
  1258. {
  1259.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1260.     {
  1261.       cc_status.flags |= CC_KNOW_HI_G1;
  1262.       cc_status.mdep = XEXP (operands[1], 0);
  1263.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
  1264.     }
  1265.   return \"ld %1,%0\;fitos %0,%0\";
  1266. }")
  1267.  
  1268. (define_insn "floatsisf2"
  1269.   [(set (match_operand:SF 0 "general_operand" "=f")
  1270.     (float:SF (match_operand:SI 1 "general_operand" "rfm")))]
  1271.   ""
  1272.   "*
  1273. {
  1274.   if (GET_CODE (operands[1]) == MEM)
  1275.     if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1276.       {
  1277.     cc_status.flags |= CC_KNOW_HI_G1;
  1278.     cc_status.mdep = XEXP (operands[1], 0);
  1279.     return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitos %0,%0\";
  1280.       }
  1281.     else
  1282.       return \"ld %1,%0\;fitos %0,%0\";
  1283.   else if (FP_REG_P (operands[1]))
  1284.     return \"fitos %1,%0\";
  1285.   return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitos %0,%0\";
  1286. }")
  1287.  
  1288. ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
  1289. ;; to be reloaded by putting the constant into memory.
  1290. ;; It must come before the more general floatsidf2 pattern.
  1291. (define_insn ""
  1292.   [(set (match_operand:DF 0 "general_operand" "=f")
  1293.     (float:DF (match_operand 1 "" "m")))]
  1294.   "GET_CODE (operands[1]) == CONST_INT"
  1295.   "*
  1296. {
  1297.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1298.     {
  1299.       cc_status.flags |= CC_KNOW_HI_G1;
  1300.       cc_status.mdep = XEXP (operands[1], 0);
  1301.       return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
  1302.     }
  1303.   return \"ld %1,%0\;fitod %0,%0\";
  1304. }")
  1305.  
  1306. (define_insn "floatsidf2"
  1307.   [(set (match_operand:DF 0 "general_operand" "=f")
  1308.     (float:DF (match_operand:SI 1 "general_operand" "rfm")))]
  1309.   ""
  1310.   "*
  1311. {
  1312.   if (GET_CODE (operands[1]) == MEM)
  1313.     if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1314.       {
  1315.     cc_status.flags |= CC_KNOW_HI_G1;
  1316.     cc_status.mdep = XEXP (operands[1], 0);
  1317.     return \"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%0\;fitod %0,%0\";
  1318.       }
  1319.     else
  1320.       return \"ld %1,%0\;fitod %0,%0\";
  1321.   else if (FP_REG_P (operands[1]))
  1322.     return \"fitod %1,%0\";
  1323.   else
  1324.     return \"st %r1,[%%fp-4]\;ld [%%fp-4],%0\;fitod %0,%0\";
  1325. }")
  1326.  
  1327. ;; Convert a float to an actual integer.
  1328. ;; Truncation is performed as part of the conversion.
  1329. (define_insn "fix_truncsfsi2"
  1330.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1331.     (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm"))))]
  1332.   ""
  1333.   "*
  1334. {
  1335.   cc_status.flags &= ~(CC_F1_IS_0);
  1336.   if (FP_REG_P (operands[1]))
  1337.     output_asm_insn (\"fstoi %1,%%f1\", operands);
  1338.   else if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1339.     {
  1340.       cc_status.flags |= CC_KNOW_HI_G1;
  1341.       cc_status.mdep = XEXP (operands[1], 0);
  1342.       output_asm_insn (\"sethi %%hi(%m1),%%g1\;ld [%%g1+%%lo(%m1)],%%f1\;fstoi %%f1,%%f1\", operands);
  1343.     }
  1344.   else
  1345.     output_asm_insn (\"ld %1,%%f1\;fstoi %%f1,%%f1\", operands);
  1346.   if (GET_CODE (operands[0]) == MEM)
  1347.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  1348.       {
  1349.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  1350.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  1351.       {
  1352.         cc_status.flags |= CC_KNOW_HI_G1;
  1353.         cc_status.mdep = XEXP (operands[0], 0);
  1354.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  1355.       }
  1356.     return \"st %%f1,[%%g1+%%lo(%m0)]\";
  1357.       }
  1358.     else
  1359.       return \"st %%f1,%0\";
  1360.   else
  1361.     return \"st %%f1,[%%fp-4]\;ld [%%fp-4],%0\";
  1362. }")
  1363.  
  1364. (define_insn "fix_truncdfsi2"
  1365.   [(set (match_operand:SI 0 "general_operand" "=rm")
  1366.     (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm"))))]
  1367.   ""
  1368.   "*
  1369. {
  1370.   cc_status.flags &= ~CC_F0_IS_0;
  1371.   if (FP_REG_P (operands[1]))
  1372.     output_asm_insn (\"fdtoi %1,%%f0\", operands);
  1373.   else
  1374.     {
  1375.       rtx xoperands[2];
  1376.       xoperands[0] = gen_rtx (REG, DFmode, 32);
  1377.       xoperands[1] = operands[1];
  1378.       output_asm_insn (output_fp_move_double (xoperands), xoperands);
  1379.       output_asm_insn (\"fdtoi %%f0,%%f0\", 0);
  1380.     }
  1381.   if (GET_CODE (operands[0]) == MEM)
  1382.     if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
  1383.       {
  1384.     if (! ((cc_prev_status.flags & CC_KNOW_HI_G1)
  1385.            && XEXP (operands[0], 0) == cc_prev_status.mdep))
  1386.       {
  1387.         cc_status.flags |= CC_KNOW_HI_G1;
  1388.         cc_status.mdep = XEXP (operands[0], 0);
  1389.         output_asm_insn (\"sethi %%hi(%m0),%%g1\", operands);
  1390.       }
  1391.     return \"st %%f0,[%%g1+%%lo(%m0)]\";
  1392.       }
  1393.     else
  1394.       return \"st %%f0,%0\";
  1395.   else
  1396.     return \"st %%f0,[%%fp-4]\;ld [%%fp-4],%0\";
  1397. }")
  1398.  
  1399. ;;- arithmetic instructions
  1400.  
  1401. (define_insn "addsi3"
  1402.   [(set (match_operand:SI 0 "register_operand" "=r")
  1403.     (plus:SI (match_operand:SI 1 "arith32_operand" "%r")
  1404.          (match_operand:SI 2 "arith32_operand" "rn")))]
  1405.   ""
  1406.   "*
  1407. {
  1408.   if (REG_P (operands[2]))
  1409.     return \"add %1,%2,%0\";
  1410.   if (SMALL_INT (operands[2]))
  1411.     return \"add %1,%2,%0\";
  1412.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1413.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;add %1,%%g1,%0\";
  1414. }")
  1415.  
  1416. (define_insn "subsi3"
  1417.   [(set (match_operand:SI 0 "register_operand" "=r")
  1418.     (minus:SI (match_operand:SI 1 "register_operand" "r")
  1419.           (match_operand:SI 2 "arith32_operand" "rn")))]
  1420.   ""
  1421.   "*
  1422. {
  1423.   if (REG_P (operands[2]))
  1424.     return \"sub %1,%2,%0\";
  1425.   if (SMALL_INT (operands[2]))
  1426.     return \"sub %1,%2,%0\";
  1427.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1428.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;sub %1,%%g1,%0\";
  1429. }")
  1430.  
  1431. (define_expand "mulsi3"
  1432.   [(set (match_operand:SI 0 "register_operand" "r")
  1433.     (mult:SI (match_operand:SI 1 "general_operand" "")
  1434.          (match_operand:SI 2 "general_operand" "")))]
  1435.   ""
  1436.   "
  1437. {
  1438.   rtx src;
  1439.  
  1440.   if (GET_CODE (operands[1]) == CONST_INT)
  1441.     if (GET_CODE (operands[2]) == CONST_INT)
  1442.       {
  1443.     emit_move_insn (operands[0],
  1444.             gen_rtx (CONST_INT, VOIDmode,
  1445.                  INTVAL (operands[1]) * INTVAL (operands[2])));
  1446.     DONE;
  1447.       }
  1448.     else
  1449.       src = gen_rtx (MULT, SImode,
  1450.              copy_to_mode_reg (SImode, operands[2]),
  1451.              operands[1]);
  1452.   else if (GET_CODE (operands[2]) == CONST_INT)
  1453.     src = gen_rtx (MULT, SImode,
  1454.            copy_to_mode_reg (SImode, operands[1]),
  1455.            operands[2]);
  1456.   else src = 0;
  1457.  
  1458.   if (src)
  1459.     emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
  1460.   else
  1461.     emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
  1462.            gen_rtx (SET, VOIDmode, operands[0],
  1463.             gen_rtx (MULT, SImode, operands[1], operands[2])),
  1464.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
  1465.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
  1466.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
  1467.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
  1468.   DONE;
  1469. }")
  1470.  
  1471. (define_expand "umulsi3"
  1472.   [(set (match_operand:SI 0 "register_operand" "r")
  1473.     (umult:SI (match_operand:SI 1 "general_operand" "")
  1474.           (match_operand:SI 2 "general_operand" "")))]
  1475.   ""
  1476.   "
  1477. {
  1478.   rtx src;
  1479.  
  1480.   if (GET_CODE (operands[1]) == CONST_INT)
  1481.     if (GET_CODE (operands[2]) == CONST_INT)
  1482.       {
  1483.     emit_move_insn (operands[0],
  1484.             gen_rtx (CONST_INT, VOIDmode,
  1485.                  (unsigned)INTVAL (operands[1]) * (unsigned)INTVAL (operands[2])));
  1486.     DONE;
  1487.       }
  1488.     else
  1489.       src = gen_rtx (UMULT, SImode,
  1490.              copy_to_mode_reg (SImode, operands[2]),
  1491.              operands[1]);
  1492.   else if (GET_CODE (operands[2]) == CONST_INT)
  1493.     src = gen_rtx (UMULT, SImode,
  1494.            copy_to_mode_reg (SImode, operands[1]),
  1495.            operands[2]);
  1496.   else src = 0;
  1497.  
  1498.   if (src)
  1499.     emit_insn (gen_rtx (SET, VOIDmode, operands[0], src));
  1500.   else
  1501.     emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
  1502.            gen_rtx (SET, VOIDmode, operands[0],
  1503.             gen_rtx (UMULT, SImode, operands[1], operands[2])),
  1504.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 8)),
  1505.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 9)),
  1506.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 12)),
  1507.            gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 13)))));
  1508.   DONE;
  1509. }")
  1510.  
  1511. (define_insn ""
  1512.   [(set (match_operand:SI 0 "register_operand" "=r")
  1513.     (mult:SI (match_operand:SI 1 "register_operand" "r")
  1514.          (match_operand:SI 2 "immediate_operand" "n")))]
  1515.   ""
  1516.   "* return output_mul_by_constant (insn, operands, 0);")
  1517.  
  1518. (define_insn ""
  1519.   [(set (match_operand:SI 0 "register_operand" "=r")
  1520.     (umult:SI (match_operand:SI 1 "register_operand" "r")
  1521.           (match_operand:SI 2 "immediate_operand" "n")))]
  1522.   ""
  1523.   "* return output_mul_by_constant (insn, operands, 1);")
  1524.  
  1525. (define_insn ""
  1526.   [(set (match_operand:SI 0 "register_operand" "=r")
  1527.     (mult:SI (match_operand:SI 1 "general_operand" "%r")
  1528.          (match_operand:SI 2 "general_operand" "r")))
  1529.    (clobber (reg:SI 8))
  1530.    (clobber (reg:SI 9))
  1531.    (clobber (reg:SI 12))
  1532.    (clobber (reg:SI 13))]
  1533.   ""
  1534.   "* return output_mul_insn (operands, 0);")
  1535.  
  1536. (define_insn ""
  1537.   [(set (match_operand:SI 0 "register_operand" "=r")
  1538.     (umult:SI (match_operand:SI 1 "general_operand" "%r")
  1539.           (match_operand:SI 2 "general_operand" "r")))
  1540.    (clobber (reg:SI 8))
  1541.    (clobber (reg:SI 9))
  1542.    (clobber (reg:SI 12))
  1543.    (clobber (reg:SI 13))]
  1544.   ""
  1545.   "* return output_mul_insn (operands, 1);")
  1546.  
  1547. ;; this pattern is needed because cse may eliminate the multiplication,
  1548. ;; but leave the clobbers behind.
  1549.  
  1550. (define_insn ""
  1551.   [(set (match_operand:SI 0 "register_operand" "=r")
  1552.     (match_operand:SI 1 "general_operand" "g"))
  1553.    (clobber (reg:SI 8))
  1554.    (clobber (reg:SI 9))
  1555.    (clobber (reg:SI 12))
  1556.    (clobber (reg:SI 13))]
  1557.   ""
  1558.   "*
  1559. {
  1560.   if (GET_CODE (operands[1]) == CONST_INT)
  1561.     {
  1562.       if (SMALL_INT (operands[1]))
  1563.     return \"mov %1,%0\";
  1564.       return \"sethi %%hi(%1),%0\;or %%lo(%1),%0,%0\";
  1565.     }
  1566.   if (GET_CODE (operands[1]) == MEM)
  1567.     return \"ld %1,%0\";
  1568.   return \"mov %1,%0\";
  1569. }")
  1570.  
  1571. ;; In case constant factor turns out to be -1.
  1572. (define_insn ""
  1573.   [(set (match_operand:SI 0 "register_operand" "=r")
  1574.     (neg:SI (match_operand:SI 1 "general_operand" "rI")))
  1575.    (clobber (reg:SI 8))
  1576.    (clobber (reg:SI 9))
  1577.    (clobber (reg:SI 12))
  1578.    (clobber (reg:SI 13))]
  1579.   ""
  1580.   "sub %%g0,%1,%0")
  1581.  
  1582. ;;- and instructions (with compliment also)               
  1583. (define_insn "andsi3"
  1584.   [(set (match_operand:SI 0 "register_operand" "=r")
  1585.     (and:SI (match_operand:SI 1 "arith32_operand" "%r")
  1586.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1587.   ""
  1588.   "*
  1589. {
  1590.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1591.     return \"and %1,%2,%0\";
  1592.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1593.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;and %1,%%g1,%0\";
  1594. }")
  1595.  
  1596. (define_insn "andcbsi3"
  1597.   [(set (match_operand:SI 0 "register_operand" "=r")
  1598.     (and:SI (match_operand:SI 1 "register_operand" "r")
  1599.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1600.   ""
  1601.   "andn %1,%2,%0")
  1602.  
  1603. (define_insn "iorsi3"
  1604.   [(set (match_operand:SI 0 "register_operand" "=r")
  1605.     (ior:SI (match_operand:SI 1 "arith32_operand" "%r")
  1606.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1607.   ""
  1608.   "*
  1609. {
  1610.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1611.     return \"or %1,%2,%0\";
  1612.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1613.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;or %1,%%g1,%0\";
  1614. }")
  1615.  
  1616. (define_insn "iorcbsi3"
  1617.   [(set (match_operand:SI 0 "register_operand" "=r")
  1618.     (ior:SI (match_operand:SI 1 "register_operand" "r")
  1619.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1620.   ""
  1621.   "orn %1,%2,%0")
  1622.  
  1623. (define_insn "xorsi3"
  1624.   [(set (match_operand:SI 0 "register_operand" "=r")
  1625.     (xor:SI (match_operand:SI 1 "arith32_operand" "%r")
  1626.         (match_operand:SI 2 "arith32_operand" "rn")))]
  1627.   ""
  1628.   "*
  1629. {
  1630.   if (REG_P (operands[2]) || SMALL_INT (operands[2]))
  1631.     return \"xor %1,%2,%0\";
  1632.   cc_status.flags &= ~CC_KNOW_HI_G1;
  1633.   return \"sethi %%hi(%2),%%g1\;or %%lo(%2),%%g1,%%g1\;xor %1,%%g1,%0\";
  1634. }")
  1635.  
  1636. (define_insn "xorcbsi3"
  1637.   [(set (match_operand:SI 0 "register_operand" "=r")
  1638.     (xor:SI (match_operand:SI 1 "register_operand" "r")
  1639.         (not:SI (match_operand:SI 2 "register_operand" "r"))))]
  1640.   ""
  1641.   "xnor %1,%2,%0")
  1642.  
  1643. ;; We cannot use the "neg" pseudo insn because the Sun assembler
  1644. ;; does not know how to make it work for constants.
  1645. (define_insn "negsi2"
  1646.   [(set (match_operand:SI 0 "general_operand" "=r")
  1647.     (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1648.   ""
  1649.   "sub %%g0,%1,%0")
  1650.  
  1651. ;; We cannot use the "not" pseudo insn because the Sun assembler
  1652. ;; does not know how to make it work for constants.
  1653. (define_insn "one_cmplsi2"
  1654.   [(set (match_operand:SI 0 "general_operand" "=r")
  1655.     (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
  1656.   ""
  1657.   "xnor %%g0,%1,%0")
  1658.  
  1659. ;; Floating point arithmetic instructions.
  1660.  
  1661. (define_insn "adddf3"
  1662.   [(set (match_operand:DF 0 "register_operand" "=f")
  1663.     (plus:DF (match_operand:DF 1 "register_operand" "f")
  1664.          (match_operand:DF 2 "register_operand" "f")))]
  1665.   ""
  1666.   "faddd %1,%2,%0")
  1667.  
  1668. (define_insn "addsf3"
  1669.   [(set (match_operand:SF 0 "register_operand" "=f")
  1670.     (plus:SF (match_operand:SF 1 "register_operand" "f")
  1671.          (match_operand:SF 2 "register_operand" "f")))]
  1672.   ""
  1673.   "fadds %1,%2,%0")
  1674.  
  1675. (define_insn "subdf3"
  1676.   [(set (match_operand:DF 0 "register_operand" "=f")
  1677.     (minus:DF (match_operand:DF 1 "register_operand" "f")
  1678.           (match_operand:DF 2 "register_operand" "f")))]
  1679.   ""
  1680.   "fsubd %1,%2,%0")
  1681.  
  1682. (define_insn "subsf3"
  1683.   [(set (match_operand:SF 0 "register_operand" "=f")
  1684.     (minus:SF (match_operand:SF 1 "register_operand" "f")
  1685.           (match_operand:SF 2 "register_operand" "f")))]
  1686.   ""
  1687.   "fsubs %1,%2,%0")
  1688.  
  1689. (define_insn "muldf3"
  1690.   [(set (match_operand:DF 0 "register_operand" "=f")
  1691.     (mult:DF (match_operand:DF 1 "register_operand" "f")
  1692.          (match_operand:DF 2 "register_operand" "f")))]
  1693.   ""
  1694.   "fmuld %1,%2,%0")
  1695.  
  1696. (define_insn "mulsf3"
  1697.   [(set (match_operand:SF 0 "register_operand" "=f")
  1698.     (mult:SF (match_operand:SF 1 "register_operand" "f")
  1699.          (match_operand:SF 2 "register_operand" "f")))]
  1700.   ""
  1701.   "fmuls %1,%2,%0")
  1702.  
  1703. (define_insn "divdf3"
  1704.   [(set (match_operand:DF 0 "register_operand" "=f")
  1705.     (div:DF (match_operand:DF 1 "register_operand" "f")
  1706.         (match_operand:DF 2 "register_operand" "f")))]
  1707.   ""
  1708.   "fdivd %1,%2,%0")
  1709.  
  1710. (define_insn "divsf3"
  1711.   [(set (match_operand:SF 0 "register_operand" "=f")
  1712.     (div:SF (match_operand:SF 1 "register_operand" "f")
  1713.         (match_operand:SF 2 "register_operand" "f")))]
  1714.   ""
  1715.   "fdivs %1,%2,%0")
  1716.  
  1717. (define_insn "negdf2"
  1718.   [(set (match_operand:DF 0 "register_operand" "=f")
  1719.     (neg:DF (match_operand:DF 1 "register_operand" "f")))]
  1720.   ""
  1721.   "*
  1722. {
  1723.   output_asm_insn (\"fnegs %1,%0\", operands);
  1724.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1725.     {
  1726.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  1727.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  1728.       output_asm_insn (\"fmovs %1,%0\", operands);
  1729.     }
  1730.   return \"\";
  1731. }")
  1732.  
  1733. (define_insn "negsf2"
  1734.   [(set (match_operand:SF 0 "register_operand" "=f")
  1735.     (neg:SF (match_operand:SF 1 "register_operand" "f")))]
  1736.   ""
  1737.   "fnegs %1,%0")
  1738.  
  1739. (define_insn "absdf2"
  1740.   [(set (match_operand:DF 0 "register_operand" "=f")
  1741.     (abs:DF (match_operand:DF 1 "register_operand" "f")))]
  1742.   ""
  1743.   "*
  1744. {
  1745.   output_asm_insn (\"fabss %1,%0\", operands);
  1746.   if (REGNO (operands[0]) != REGNO (operands[1]))
  1747.     {
  1748.       operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
  1749.       operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
  1750.       output_asm_insn (\"fmovs %1,%0\", operands);
  1751.     }
  1752.   return \"\";
  1753. }")
  1754.  
  1755. (define_insn "abssf2"
  1756.   [(set (match_operand:SF 0 "register_operand" "=f")
  1757.     (abs:SF (match_operand:SF 1 "register_operand" "f")))]
  1758.   ""
  1759.   "fabss %1,%0")
  1760.  
  1761. ;; Shift instructions
  1762.  
  1763. ;; Optimized special case of shifting.
  1764. ;; Must precede the general case.
  1765.  
  1766. (define_insn ""
  1767.   [(set (match_operand:SI 0 "register_operand" "=r")
  1768.     (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1769.              (const_int 24)))]
  1770.   ""
  1771.   "*
  1772. {
  1773.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1774.     {
  1775.       cc_status.flags |= CC_KNOW_HI_G1;
  1776.       cc_status.mdep = XEXP (operands[1], 0);
  1777.       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
  1778.     }
  1779.   return \"ldsb %1,%0\";
  1780. }")
  1781.  
  1782. (define_insn ""
  1783.   [(set (match_operand:SI 0 "register_operand" "=r")
  1784.     (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
  1785.              (const_int 24)))]
  1786.   ""
  1787.   "*
  1788. {
  1789.   if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
  1790.     {
  1791.       cc_status.flags |= CC_KNOW_HI_G1;
  1792.       cc_status.mdep = XEXP (operands[1], 0);
  1793.       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
  1794.     }
  1795.   return \"ldub %1,%0\";
  1796. }")
  1797.  
  1798. ;;- arithmetic shift instructions
  1799. (define_insn "ashlsi3"
  1800.   [(set (match_operand:SI 0 "register_operand" "=r")
  1801.     (ashift:SI (match_operand:SI 1 "register_operand" "r")
  1802.            (match_operand:SI 2 "arith32_operand" "rn")))]
  1803.   ""
  1804.   "*
  1805. {
  1806.   if (GET_CODE (operands[2]) == CONST_INT
  1807.       && INTVAL (operands[2]) >= 32)
  1808.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1809.   return \"sll %1,%2,%0\";
  1810. }")
  1811.  
  1812. (define_insn "ashrsi3"
  1813.   [(set (match_operand:SI 0 "register_operand" "=r")
  1814.     (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1815.              (match_operand:SI 2 "arith32_operand" "rn")))]
  1816.   ""
  1817.   "*
  1818. {
  1819.   if (GET_CODE (operands[2]) == CONST_INT
  1820.       && INTVAL (operands[2]) >= 32)
  1821.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1822.   return \"sra %1,%2,%0\";
  1823. }")
  1824.  
  1825. (define_insn "lshrsi3"
  1826.   [(set (match_operand:SI 0 "register_operand" "=r")
  1827.     (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
  1828.              (match_operand:SI 2 "arith32_operand" "rn")))]
  1829.   ""
  1830.   "*
  1831. {
  1832.   if (GET_CODE (operands[2]) == CONST_INT
  1833.       && INTVAL (operands[2]) >= 32)
  1834.     operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 31);
  1835.   return \"srl %1,%2,%0\";
  1836. }")
  1837.  
  1838. ;; Unconditional and other jump instructions
  1839. ;; Note that for the Sparc, by setting the annul bit on an unconditional
  1840. ;; branch, the following insn is never executed.  This saves us a nop,
  1841. ;; but requires a debugger which can handle annuled branches.
  1842. (define_insn "jump"
  1843.   [(set (pc) (label_ref (match_operand 0 "" "")))]
  1844.   ""
  1845.   "*
  1846. {
  1847.   extern int optimize;
  1848.   extern int flag_no_peephole;
  1849.  
  1850.   if (optimize && !flag_no_peephole)
  1851.     return \"b,a %l0\";
  1852.   return \"b %l0\;nop\";
  1853. }")
  1854.  
  1855. ;; Peephole optimizers recognize a few simple cases when delay insns are safe.
  1856. ;; Complex ones are up front.  Simple ones after.
  1857.  
  1858. ;; This pattern is just like the following one, but matches when there
  1859. ;; is a jump insn after the "delay" insn.  Without this pattern, we
  1860. ;; de-optimize that case.
  1861.  
  1862. (define_peephole
  1863.   [(set (pc) (match_operand 0 "" ""))
  1864.    (set (match_operand:SI 1 "" "")
  1865.     (match_operand:SI 2 "" ""))
  1866.    (set (pc) (label_ref (match_operand 3 "" "")))]
  1867.   "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 2)"
  1868.   "*
  1869. {
  1870.   rtx xoperands[2];
  1871.   rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
  1872.   rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
  1873.   rtx label, head;
  1874.   int parity;
  1875.  
  1876.   if (GET_CODE (XEXP (operands[0], 1)) == PC)
  1877.     {
  1878.       parity = 1;
  1879.       label = XEXP (XEXP (operands[0], 2), 0);
  1880.     }
  1881.   else
  1882.     {
  1883.       parity = 0;
  1884.       label = XEXP (XEXP (operands[0], 1), 0);
  1885.     }
  1886.   xoperands[0] = XEXP (operands[0], 0);
  1887.   xoperands[1] = label;
  1888.  
  1889.   head = next_real_insn_no_labels (label);
  1890.  
  1891.   /* If at the target of this label we set the condition codes,
  1892.      and the condition codes are already set for that value,
  1893.      advance, if we can, to the following insn.  */
  1894.   if (GET_CODE (PATTERN (head)) == SET
  1895.       && GET_CODE (SET_DEST (PATTERN (head))) == CC0
  1896.       && cc_status.value2 == SET_SRC (PATTERN (head)))
  1897.     {
  1898.       rtx nhead = next_real_insn_no_labels (head);
  1899.       if (nhead
  1900.       && GET_CODE (nhead) == INSN
  1901.       && GET_CODE (PATTERN (nhead)) == SET
  1902.       && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
  1903.                       GET_MODE (SET_DEST (PATTERN (nhead))))
  1904.       && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
  1905.       /* Moves between FP regs and CPU regs are two insns.  */
  1906.       && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
  1907.            && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
  1908.            && (FP_REG_P (SET_SRC (PATTERN (nhead)))
  1909.            != FP_REG_P (SET_DEST (PATTERN (nhead))))))
  1910.     {
  1911.       head = nhead;
  1912.     }
  1913.     }
  1914.  
  1915.   /* Output the branch instruction first.  */
  1916.   if (cc_prev_status.flags & CC_IN_FCCR)
  1917.     {
  1918.       if (parity)
  1919.     output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
  1920.       else
  1921.     output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
  1922.     }
  1923.   else
  1924.     {
  1925.       if (parity)
  1926.     output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
  1927.       else
  1928.     output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
  1929.     }
  1930.  
  1931.   /* Now steal the first insn of the target.  */
  1932.   output_eager_then_insn (head, operands);
  1933.  
  1934.   XVECEXP (PATTERN (insn), 0, 0) = XVECEXP (PATTERN (insn), 0, 1);
  1935.   XVECEXP (PATTERN (insn), 0, 1) = XVECEXP (PATTERN (insn), 0, 2);
  1936.  
  1937.   return output_delayed_branch (\"b %l3 ! eager2\", operands, insn);
  1938. }")
  1939.  
  1940. ;; Here is a peephole which recognizes where delay insns can be made safe:
  1941. ;; (1) following a conditional branch, if the target of the conditional branch
  1942. ;; has only one user (this insn), move the first insn into our delay slot
  1943. ;; and emit an annulled branch.
  1944. ;; (2) following a conditional branch, if we can execute the fall-through
  1945. ;; insn without risking any evil effects, then do that instead of a nop.
  1946.  
  1947. (define_peephole
  1948.   [(set (pc) (match_operand 0 "" ""))
  1949.    (set (match_operand:SI 1 "" "")
  1950.     (match_operand:SI 2 "" ""))]
  1951.   "TARGET_EAGER && operands_satisfy_eager_branch_peephole (operands, 1)"
  1952.   "*
  1953. {
  1954.   rtx xoperands[2];
  1955.   rtx pat = gen_rtx (SET, VOIDmode, operands[1], operands[2]);
  1956.   rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
  1957.   rtx label, head, prev = (rtx)1;
  1958.   int parity;
  1959.  
  1960.   if (GET_CODE (XEXP (operands[0], 1)) == PC)
  1961.     {
  1962.       parity = 1;
  1963.       label = XEXP (XEXP (operands[0], 2), 0);
  1964.     }
  1965.   else
  1966.     {
  1967.       parity = 0;
  1968.       label = XEXP (XEXP (operands[0], 1), 0);
  1969.     }
  1970.   xoperands[0] = XEXP (operands[0], 0);
  1971.   xoperands[1] = label;
  1972.  
  1973.   if (LABEL_NUSES (label) == 1)
  1974.     {
  1975.       prev = PREV_INSN (label);
  1976.       while (prev
  1977.          && (GET_CODE (prev) == NOTE
  1978.          || (GET_CODE (prev) == INSN
  1979.              && (GET_CODE (PATTERN (prev)) == CLOBBER
  1980.              || GET_CODE (PATTERN (prev)) == USE))))
  1981.     prev = PREV_INSN (prev);
  1982.       if (prev == 0
  1983.       || GET_CODE (prev) == BARRIER)
  1984.     {
  1985.       prev = 0;
  1986.       head = next_real_insn_no_labels (label);
  1987.     }
  1988.     }
  1989.   if (prev == 0
  1990.       && head != 0
  1991.       && ! INSN_DELETED_P (head)
  1992.       && GET_CODE (head) == INSN
  1993.       && GET_CODE (PATTERN (head)) == SET
  1994.       && strict_single_insn_op_p (SET_SRC (PATTERN (head)),
  1995.                   GET_MODE (SET_DEST (PATTERN (head))))
  1996.       && strict_single_insn_op_p (SET_DEST (PATTERN (head)), VOIDmode)
  1997.       /* Moves between FP regs and CPU regs are two insns.  */
  1998.       && !(GET_CODE (SET_SRC (PATTERN (head))) == REG
  1999.        && GET_CODE (SET_DEST (PATTERN (head))) == REG
  2000.        && (FP_REG_P (SET_SRC (PATTERN (head)))
  2001.            != FP_REG_P (SET_DEST (PATTERN (head))))))
  2002.     {
  2003.       /* If at the target of this label we set the condition codes,
  2004.      and the condition codes are already set for that value,
  2005.      advance, if we can, to the following insn.  */
  2006.       if (GET_CODE (PATTERN (head)) == SET
  2007.       && GET_CODE (SET_DEST (PATTERN (head))) == CC0
  2008.       && cc_status.value2 == SET_SRC (PATTERN (head)))
  2009.     {
  2010.       rtx nhead = next_real_insn_no_labels (head);
  2011.       if (nhead
  2012.           && GET_CODE (nhead) == INSN
  2013.           && GET_CODE (PATTERN (nhead)) == SET
  2014.           && strict_single_insn_op_p (SET_SRC (PATTERN (nhead)),
  2015.                       GET_MODE (SET_DEST (nhead)))
  2016.           && strict_single_insn_op_p (SET_DEST (PATTERN (nhead)), VOIDmode)
  2017.           /* Moves between FP regs and CPU regs are two insns.  */
  2018.           && !(GET_CODE (SET_SRC (PATTERN (nhead))) == REG
  2019.            && GET_CODE (SET_DEST (PATTERN (nhead))) == REG
  2020.            && (FP_REG_P (SET_SRC (PATTERN (nhead)))
  2021.                != FP_REG_P (SET_DEST (PATTERN (nhead))))))
  2022.         head = nhead;
  2023.     }
  2024.  
  2025.       /* Output the branch instruction first.  */
  2026.       if (cc_prev_status.flags & CC_IN_FCCR)
  2027.     {
  2028.       if (parity)
  2029.         output_asm_insn (\"fb%F0,a %l1 ! eager\", xoperands);
  2030.       else
  2031.         output_asm_insn (\"fb%C0,a %l1 ! eager\", xoperands);
  2032.     }
  2033.       else
  2034.     {
  2035.       if (parity)
  2036.         output_asm_insn (\"b%N0,a %l1 ! eager\", xoperands);
  2037.       else
  2038.         output_asm_insn (\"b%C0,a %l1 ! eager\", xoperands);
  2039.     }
  2040.  
  2041.       /* Now steal the first insn of the target.  */
  2042.       output_eager_then_insn (head, operands);
  2043.     }
  2044.   else
  2045.     {
  2046.       /* Output the branch instruction first.  */
  2047.       if (cc_prev_status.flags & CC_IN_FCCR)
  2048.     {
  2049.       if (parity)
  2050.         output_asm_insn (\"fb%F0 %l1 ! eager\", xoperands);
  2051.       else
  2052.         output_asm_insn (\"fb%C0 %l1 ! eager\", xoperands);
  2053.     }
  2054.       else
  2055.     {
  2056.       if (parity)
  2057.         output_asm_insn (\"b%N0 %l1 ! eager\", xoperands);
  2058.       else
  2059.         output_asm_insn (\"b%C0 %l1 ! eager\", xoperands);
  2060.     }
  2061.     }
  2062.   return output_delay_insn (delay_insn);
  2063. }")
  2064.  
  2065. ;; Here are two simple peepholes which fill the delay slot of
  2066. ;; an unconditional branch.
  2067.  
  2068. (define_peephole
  2069.   [(set (match_operand:SI 0 "register_operand" "=r")
  2070.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2071.    (set (pc) (label_ref (match_operand 2 "" "")))]
  2072.   "single_insn_extra_test (operands[0], operands[1])"
  2073.   "* return output_delayed_branch (\"b %l2\", operands, insn);")
  2074.  
  2075. (define_peephole
  2076.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2077.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2078.    (set (pc) (label_ref (match_operand 2 "" "")))]
  2079.   ""
  2080.   "* return output_delayed_branch (\"b %l2\", operands, insn);")
  2081.  
  2082. (define_insn "tablejump"
  2083.   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
  2084.    (use (label_ref (match_operand 1 "" "")))]
  2085.   ""
  2086.   "jmp %0\;nop")
  2087.  
  2088. (define_peephole
  2089.   [(set (match_operand:SI 0 "register_operand" "=r")
  2090.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2091.    (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
  2092.           (use (label_ref (match_operand 3 "" "")))])]
  2093.   "REGNO (operands[0]) != REGNO (operands[2])
  2094.    && single_insn_extra_test (operands[0], operands[1])"
  2095.   "* return output_delayed_branch (\"jmp %2\", operands, insn);")
  2096.  
  2097. (define_peephole
  2098.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2099.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2100.    (parallel [(set (pc) (match_operand:SI 2 "register_operand" "r"))
  2101.           (use (label_ref (match_operand 3 "" "")))])]
  2102.   ""
  2103.   "* return output_delayed_branch (\"jmp %2\", operands, insn);")
  2104.  
  2105. ;;- jump to subroutine
  2106. (define_expand "call"
  2107.   [(call (match_operand:SI 0 "memory_operand" "m")
  2108.      (match_operand 1 "" "i"))]
  2109.   ;; operand[2] is next_arg_register
  2110.   ""
  2111.   "
  2112. {
  2113.   rtx fn_rtx, nregs_rtx;
  2114.  
  2115.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[0], 0)) == REG)
  2116.     {
  2117.       rtx g1_rtx = gen_rtx (REG, SImode, 1);
  2118.       emit_move_insn (g1_rtx, XEXP (operands[0], 0));
  2119.       fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
  2120.     }
  2121.   else
  2122.     fn_rtx = operands[0];
  2123.  
  2124.   /* Count the number of parameter registers being used by this call.
  2125.      if that argument is NULL, it means we are using them all, which
  2126.      means 6 on the sparc.  */
  2127. #if 0
  2128.   if (operands[2])
  2129.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
  2130.   else
  2131.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2132. #else
  2133.   nregs_rtx = const0_rtx;
  2134. #endif
  2135.  
  2136.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
  2137.                gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
  2138.                gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)))));
  2139.   DONE;
  2140. }")
  2141.  
  2142. (define_insn ""
  2143.   [(call (match_operand:SI 0 "memory_operand" "m")
  2144.      (match_operand 1 "" "i"))
  2145.    (use (reg:SI 31))]
  2146.   ;;- Don't use operand 1 for most machines.
  2147.   ""
  2148.   "*
  2149. {
  2150.   /* strip the MEM.  */
  2151.   operands[0] = XEXP (operands[0], 0);
  2152.   CC_STATUS_INIT;
  2153.   if (TARGET_SUN_ASM && GET_CODE (operands[0]) == REG)
  2154.     return \"jmpl %a0,%%o7\;nop\";
  2155.   return \"call %a0,%1\;nop\";
  2156. }")
  2157.  
  2158. (define_peephole
  2159.   [(set (match_operand:SI 0 "register_operand" "=r")
  2160.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2161.    (parallel [(call (match_operand:SI 2 "memory_operand" "m")
  2162.             (match_operand 3 "" "i"))
  2163.           (use (reg:SI 31))])]
  2164.   ;;- Don't use operand 1 for most machines.
  2165.   "! reg_mentioned_p (operands[0], operands[2])
  2166.    && single_insn_extra_test (operands[0], operands[1])"
  2167.   "*
  2168. {
  2169.   /* strip the MEM.  */
  2170.   operands[2] = XEXP (operands[2], 0);
  2171.   if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
  2172.     return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
  2173.   return output_delayed_branch (\"call %a2,%3\", operands, insn);
  2174. }")
  2175.  
  2176. (define_peephole
  2177.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2178.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2179.    (parallel [(call (match_operand:SI 2 "memory_operand" "m")
  2180.             (match_operand 3 "" "i"))
  2181.           (use (reg:SI 31))])]
  2182.   ;;- Don't use operand 1 for most machines.
  2183.   ""
  2184.   "*
  2185. {
  2186.   /* strip the MEM.  */
  2187.   operands[2] = XEXP (operands[2], 0);
  2188.   if (TARGET_SUN_ASM && GET_CODE (operands[2]) == REG)
  2189.     return output_delayed_branch (\"jmpl %a2,%%o7\", operands, insn);
  2190.   return output_delayed_branch (\"call %a2,%3\", operands, insn);
  2191. }")
  2192.  
  2193. (define_expand "call_value"
  2194.   [(set (match_operand 0 "register_operand" "=rf")
  2195.     (call (match_operand:SI 1 "memory_operand" "m")
  2196.           (match_operand 2 "" "i")))]
  2197.   ;; operand 3 is next_arg_register
  2198.   ""
  2199.   "
  2200. {
  2201.   rtx fn_rtx, nregs_rtx;
  2202.   rtvec vec;
  2203.  
  2204.   if (TARGET_SUN_ASM && GET_CODE (XEXP (operands[1], 0)) == REG)
  2205.     {
  2206.       rtx g1_rtx = gen_rtx (REG, SImode, 1);
  2207.       emit_move_insn (g1_rtx, XEXP (operands[1], 0));
  2208.       fn_rtx = gen_rtx (MEM, SImode, g1_rtx);
  2209.     }
  2210.   else
  2211.     fn_rtx = operands[1];
  2212.  
  2213. #if 0
  2214.   if (operands[3])
  2215.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
  2216.   else
  2217.     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
  2218. #else
  2219.   nregs_rtx = const0_rtx;
  2220. #endif
  2221.  
  2222.   vec = gen_rtvec (2,
  2223.            gen_rtx (SET, VOIDmode, operands[0],
  2224.                 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
  2225.            gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31)));
  2226.  
  2227.   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
  2228.   DONE;
  2229. }")
  2230.  
  2231. (define_insn ""
  2232.   [(set (match_operand 0 "" "=rf")
  2233.     (call (match_operand:SI 1 "memory_operand" "m")
  2234.           (match_operand 2 "" "i")))
  2235.    (use (reg:SI 31))]
  2236.   ;;- Don't use operand 2 for most machines.
  2237.   ""
  2238.   "*
  2239. {
  2240.   /* strip the MEM.  */
  2241.   operands[1] = XEXP (operands[1], 0);
  2242.   CC_STATUS_INIT;
  2243.   if (TARGET_SUN_ASM && GET_CODE (operands[1]) == REG)
  2244.     return \"jmpl %a1,%%o7\;nop\";
  2245.   return \"call %a1,%2\;nop\";
  2246. }")
  2247.  
  2248. (define_peephole
  2249.   [(set (match_operand:SI 0 "register_operand" "=r")
  2250.     (match_operand:SI 1 "single_insn_src_p" "p"))
  2251.    (parallel [(set (match_operand 2 "" "=rf")
  2252.            (call (match_operand:SI 3 "memory_operand" "m")
  2253.              (match_operand 4 "" "i")))
  2254.           (use (reg:SI 31))])]
  2255.   ;;- Don't use operand 4 for most machines.
  2256.   "! reg_mentioned_p (operands[0], operands[3])
  2257.    && single_insn_extra_test (operands[0], operands[1])"
  2258.   "*
  2259. {
  2260.   /* strip the MEM.  */
  2261.   operands[3] = XEXP (operands[3], 0);
  2262.   if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
  2263.     return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
  2264.   return output_delayed_branch (\"call %a3,%4\", operands, insn);
  2265. }")
  2266.  
  2267. (define_peephole
  2268.   [(set (match_operand:SI 0 "memory_operand" "=m")
  2269.     (match_operand:SI 1 "reg_or_0_operand" "rJ"))
  2270.    (parallel [(set (match_operand 2 "" "=rf")
  2271.            (call (match_operand:SI 3 "memory_operand" "m")
  2272.              (match_operand 4 "" "i")))
  2273.           (use (reg:SI 31))])]
  2274.   ;;- Don't use operand 4 for most machines.
  2275.   ""
  2276.   "*
  2277. {
  2278.   /* strip the MEM.  */
  2279.   operands[3] = XEXP (operands[3], 0);
  2280.   if (TARGET_SUN_ASM && GET_CODE (operands[3]) == REG)
  2281.     return output_delayed_branch (\"jmpl %a3,%%o7\", operands, insn);
  2282.   return output_delayed_branch (\"call %a3,%4\", operands, insn);
  2283. }")
  2284.  
  2285. (define_insn "return"
  2286.   [(return)]
  2287.   "! TARGET_EPILOGUE"
  2288.   "ret\;restore")
  2289.  
  2290. (define_peephole
  2291.   [(set (reg:SI 24)
  2292.     (match_operand:SI 0 "reg_or_0_operand" "rJ"))
  2293.    (return)]
  2294.   "! TARGET_EPILOGUE"
  2295.   "ret\;restore %r0,0x0,%%o0")
  2296.  
  2297. (define_peephole
  2298.   [(set (reg:SI 24)
  2299.     (plus:SI (match_operand:SI 0 "register_operand" "r%")
  2300.          (match_operand:SI 1 "arith_operand" "rI")))
  2301.    (return)]
  2302.   "! TARGET_EPILOGUE"
  2303.   "ret\;restore %r0,%1,%%o0")
  2304.  
  2305. (define_peephole
  2306.   [(set (reg:SI 24)
  2307.     (minus:SI (match_operand:SI 0 "register_operand" "r")
  2308.           (match_operand:SI 1 "small_int" "I")))
  2309.    (return)]
  2310.   "! TARGET_EPILOGUE"
  2311.   "ret\;restore %0,-(%1),%%o0")
  2312.  
  2313. (define_insn "nop"
  2314.   [(const_int 0)]
  2315.   ""
  2316.   "nop")
  2317.  
  2318. ;;- Local variables:
  2319. ;;- mode:emacs-lisp
  2320. ;;- comment-start: ";;- "
  2321. ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
  2322. ;;- eval: (modify-syntax-entry ?[ "(]")
  2323. ;;- eval: (modify-syntax-entry ?] ")[")
  2324. ;;- eval: (modify-syntax-entry ?{ "(}")
  2325. ;;- eval: (modify-syntax-entry ?} "){")
  2326. ;;- End:
  2327.  
  2328.